using System;
using System.IO;
using System.Windows.Forms;
using System.ComponentModel;
using PluginCore.Utilities;
using PluginCore.Helpers;
using PluginCore;
using ASCompletion.Context;
using PluginCore.Managers;

namespace MultiGenerator
{
	public class PluginMain : IPlugin
	{
		// plugin based on SourceOption by Allessandro
		// and original sources of FD
        private String pluginName = "MultiGenerator";
		private String pluginGuid = "ed94ae94-30cd-443e-b0e9-a52f1c284d14";
        private String pluginHelp = "www.kulkoff.com";
		private String pluginDesc = "Multi Getters/Setters/Accessor generator for FlashDevelop3.";
        private String pluginAuth = "Yuriy (Mur4ik) Kulkoff";
        
        private String settingFilename;
        
        private Settings settingObject;
        
        private PluginUI pluginDialog;
		
        ToolStripMenuItem contextMenu;
        ToolStripSeparator separator;
        ToolStripMenuItem multiGeneratorMenu;

		private Boolean truncateImports = false;
		private int deletedImportsCompensation;
		
        public static IMainForm MainForm { get { return PluginBase.MainForm; } }

	    #region Required Properties

        /// <summary>
        /// Name of the plugin
        /// </summary> 
        public String Name
		{
			get { return this.pluginName; }
		}

        /// <summary>
        /// GUID of the plugin
        /// </summary>
        public String Guid
		{
			get { return this.pluginGuid; }
		}

        /// <summary>
        /// Author of the plugin
        /// </summary> 
        public String Author
		{
			get { return this.pluginAuth; }
		}

        /// <summary>
        /// Description of the plugin
        /// </summary> 
        public String Description
		{
			get { return this.pluginDesc; }
		}

        /// <summary>
        /// Web address for help
        /// </summary> 
        public String Help
		{
			get { return this.pluginHelp; }
		}

        /// <summary>
        /// Object that contains the settings
        /// </summary>
        [Browsable(false)]
        public Object Settings
        {
			get { return this.settingObject; }
        }
		
		#endregion
		
		#region Required Methods
		
		/// <summary>
		/// Initializes the plugin
		/// </summary>
		public void Initialize()
		{
            this.InitBasics();
            this.LoadSettings();
            this.AddEventHandlers();
            this.InitLocalization();
            this.CreateContextMenu();
        }
		
		/// <summary>
		/// Disposes the plugin
		/// </summary>
		public void Dispose()
		{
            this.SaveSettings();
		}
		
		/// <summary>
		/// Handles the incoming events
		/// </summary>
		public void HandleEvent(Object sender, NotifyEvent e, HandlingPriority prority)
		{
			switch (e.Type)
			{
				case EventType.Keys:
					Keys key = (e as KeyEvent).Value;
					if (key == this.settingObject.ShowGeneratorForm)
					{
						e.Handled = true;
						GenerateMultipleMebersMethods(null, null);
					}
					break;
			}
		}
		
		#endregion

        #region Custom Methods
       
        /// <summary>
        /// Initializes important variables
        /// </summary>
        public void InitBasics()
        {
			String dataPath = Path.Combine(PathHelper.DataDir, "MultiGenerator");
            if (!Directory.Exists(dataPath)) Directory.CreateDirectory(dataPath);
            this.settingFilename = Path.Combine(dataPath, "Settings.fdb");
        }

        /// <summary>
        /// Adds the required event handlers
        /// </summary> 
        public void AddEventHandlers()
        {
			EventManager.AddEventHandler(this, EventType.Keys);
        }

        /// <summary>
        /// Initializes the localization of the plugin
        /// </summary>
        public void InitLocalization()
        {
			
        }

        /// <summary>
        /// Loads the plugin settings
        /// </summary>
        public void LoadSettings()
        {
            this.settingObject = new Settings();
            if (!File.Exists(this.settingFilename)) this.SaveSettings();
            else
            {
                Object obj = ObjectSerializer.Deserialize(this.settingFilename, this.settingObject);
                this.settingObject = (Settings)obj;
            }
        }

        /// <summary>
        /// Saves the plugin settings
        /// </summary>
        public void SaveSettings()
        {
            ObjectSerializer.Serialize(this.settingFilename, this.settingObject);
        }

		private void TestTrace(object sender, EventArgs e)
		{
			
		}
		
		/// <summary>
        /// Create Getters/Setters methods from a class variable
        /// </summary>
        private void GenerateMultipleMebersMethods(object sender, EventArgs e)
		{
			IASContext context = ASContext.Context;
			pluginDialog = new PluginUI();
			pluginDialog.ContextClass = context.CurrentClass;
			pluginDialog.FillMemberList();
			
			if (pluginDialog.ShowDialog() == DialogResult.OK)
			{
				if (pluginDialog.methodsNames != null && pluginDialog.methodsNames.Length > 0)
				{
					// implement renaming functionnality and java-stile accessor
				}
			}
		}
		
        private void CreateContextMenu()
        {
			contextMenu = new ToolStripMenuItem("MultiGenerator");
			multiGeneratorMenu = new ToolStripMenuItem("Multiple property generator", null, new EventHandler(this.GenerateMultipleMebersMethods), this.settingObject.ShowGeneratorForm);
            separator = new ToolStripSeparator();
			
            contextMenu.DropDownItems.Add( multiGeneratorMenu );
			//contextMenu.DropDownItems.Add(new ToolStripSeparator());
			//contextMenu.DropDownItems.Add(new ToolStripMenuItem("Test Log", null, new EventHandler(this.TestTrace)));

            MainForm.EditorMenu.Opening += this.EditorMenu_openHandler;
            MainForm.EditorMenu.Closed  += this.EditorMenu_closeHandler;
        }

        /// <summary>
        /// Before the scintilla menu opens, check which menu item to display into
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		private void EditorMenu_openHandler(object sender, EventArgs e)
        {
            IASContext context = ASContext.Context.CurrentModel.Context;

            if (context != null && (context.GetType().ToString().Equals("AS2Context.Context") || context.GetType().ToString().Equals("AS3Context.Context")))
            {
                if (!MainForm.EditorMenu.Items.Contains(contextMenu))
                {
                    MainForm.EditorMenu.Items.Add(separator);
                    MainForm.EditorMenu.Items.Add(contextMenu);
                }
            }
        }

		private void EditorMenu_closeHandler(object sender, EventArgs e)
        {
            if(MainForm.EditorMenu.Items.Contains(separator))
                MainForm.EditorMenu.Items.Remove(separator);

            if(MainForm.EditorMenu.Items.Contains(contextMenu))
                MainForm.EditorMenu.Items.Remove(contextMenu);
        }
		
		#endregion
	}
}